<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>

    function fn(a, b, c, d){
      console.log(a,b,c,d)
    }
    const newFn = fn.bind('ctx',1,2)
    newFn(3,4)
    /* 手写bind */
    Function.prototype.myBind = function(ctx, ...args) {
      if(typeof this !== "fucntion") {
        throw new Error("type error")
      }
      const fn = this
      return function(...subArgs) {
        const allArgs = [...args, ...subArgs]
        if(new.target) {
          return new fn(...allArgs)
        } else {
          //fn的this, 指向ctx
          return fn.apply(ctx, allArgs)
        }
      }
    }
      /* 手写call */
      Function.prototype.myCall = function(ctx, ...args) {
        if(typeof this !== "function"){
          throw new Error('Type Error')
        }
        ctx = ctx === null || ctx === undefined ? globalThis : Object(ctx)
        const fn = this
        //fn的this, 指向ctx 最简单的防范ctx.fn() ctx:{key: fn}
        const key = Symbol()
        ctx[key] = fn
        const res = ctx[key](...args)
        delete ctx[key]
        return res
      }

      /* 手写apply */
      Function.prototype.myApply = function(context, args) {
        if(typeof this !== "function"){
          return new Error('Type Error')
        }
        context = context === null || undefined ? globalThis : Object(context)
        const fn = Symbol()
        context[fn] = this
        const result = context[fn](...args)
        delete context[fn]
        return result
      }
  </script>
</body>
</html>